import folium
# Singapore's coordinates according to Google: 1.3521° N, 103.8198° E
sg_map = folium.Map(location=[1.3521, 103.8198], zoom_start=12)
sg_map
Dataframes are a construct in R used to store data
import pandas as pd
fname = "data/resale-flat-prices/resale-flat-prices-based-on-registration-date-from-jan-2015-onwards.csv"
df = pd.read_csv(fname)
df.head()
We filter out entries for just the year 2017 to make plotting a bit faster.
df = df[df["month"].str.contains("2017")].reset_index(drop=True)
Many of the columns are not very useful for the purposes of mapping so we drop them
df = df.drop(["month", "flat_type", "storey_range", 'flat_model', "lease_commence_date", "remaining_lease"],axis=1)
# Look at the number of rows and columns
print(df.shape)
df.head()
df["ppsm"] = df.resale_price/df.floor_area_sqm
# Normalization to get prices in a 0-1 range
max_ppsm = df.ppsm.max()
min_ppsm = df.ppsm.min()
df["normalized"] = df.ppsm.apply(lambda x: (x - min_ppsm)/(max_ppsm - min_ppsm))
df.head()
We use the onemap api which geocodes Singaporean addresses: https://docs.onemap.sg/#authentication-service-post
import requests
def geocode(block, streetname):
url = "https://developers.onemap.sg/commonapi/search?"
address = block + " " + streetname
address = address.replace(" ", "%20")
http_req = url + "searchVal=" + address + "&returnGeom=Y&getAddrDetails=Y&pageNum=1"
r = requests.get(http_req)
try:
lat = r.json()["results"][0]["LATITUDE"]
lng = r.json()["results"][0]["LONGITUDE"]
except:
# print(http_req)
# print(r.json()["results"])
return 0, 0
return float(lat),float(lng)
import colorsys
from tqdm import *
for i in tqdm(range(df.shape[0])):
blk = df.iloc[i]["block"]
streetname = df.iloc[i]["street_name"]
lat, lng = geocode(blk,streetname)
# Ignore geocoding errors
if lat == 0 and lng == 0:
continue
price = df.iloc[i]["resale_price"]
normalized_price = df.iloc[i]["normalized"]
# assign a colour based on the position of the value in the range of 0 to 1
fc = "#%02x%02x%02x" % tuple(map(lambda x: int(x * 255), colorsys.hsv_to_rgb(normalized_price,1,1)))
folium.RegularPolygonMarker(
[lat, lng],
popup="$" + str(int(price)),
fill_color=fc,
number_of_sides=4,
radius=5
).add_to(sg_map)